package com.elitel.frame.base.service.impl;

import com.elitel.frame.base.service.BaseQueryfieldService;
import com.elitel.frame.base.service.PolymService;
import com.elitel.frame.base.service.SysPrjServiceService;
import com.elitel.frame.main.dao.BaseSqlFieldTypeMapper;
import com.elitel.frame.main.dao.SysPrjserviceMapper;
import com.elitel.frame.main.dao.ext.ExtBaseQueryfieldMapper;
import com.elitel.frame.main.dao.ext.ExtBaseShowfieldMapper;
import com.elitel.frame.main.dao.ext.ExtSysPrjserviceMapper;
import com.elitel.frame.main.dao.polym.CfgMultQueryFieldMapper;
import com.elitel.frame.main.dao.polym.CfgMultRelationFieldMapper;
import com.elitel.frame.main.dao.polym.CfgMultRelationMapper;
import com.elitel.frame.main.dao.polym.CfgMultResultFieldMapper;
import com.elitel.frame.main.entity.BaseQueryfield;
import com.elitel.frame.main.entity.BaseSqlFieldType;
import com.elitel.frame.main.entity.SysPrjservice;
import com.elitel.frame.main.entity.ext.BaseShowfieldExt;
import com.elitel.frame.main.entity.ext.PrjServiceExt;
import com.elitel.frame.main.entity.polym.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author mulis
 */
@Service
public class PolymServiceImpl implements PolymService {

    @Autowired
    private BaseQueryfieldService baseQueryfieldService;
    @Autowired
    private ExtSysPrjserviceMapper extSysPrjserviceMapper;


    @Autowired
    private CfgMultQueryFieldMapper cfgMultQueryFieldMapper;


    @Autowired
    private CfgMultResultFieldMapper cfgMultResultFieldMapper;

    @Autowired
    private ExtBaseQueryfieldMapper extBaseQueryfieldMapper;


    @Autowired
    private BaseSqlFieldTypeMapper sqlFieldTypeMapper;


    @Autowired
    private ExtBaseShowfieldMapper extBaseShowfieldMapper;

    @Autowired
    private SysPrjServiceService sysPrjServiceService;


    @Autowired
    private SysPrjserviceMapper sysPrjserviceMapper;


    @Autowired
    private CfgMultRelationMapper cfgMultRelationMapper;

    @Autowired
    private CfgMultRelationFieldMapper cfgMultRelationFieldMapper;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveCfgInfo(PolymVO params) throws JsonProcessingException {
        // 配置信息
        SysPrjservice cfgInfo = params.getCfgInfo();
        // 关联信息
        PolymRelVO relVO = params.getRelInfo();
        // 保存服务基本配置信息
        sysPrjServiceService.savePrjInfo(cfgInfo);
        // 保存服务基本配置关联信息
        this.saveRel(relVO.getCfgMultRelation());
        // 保存关联字段信息
        this.saveFieldRel(relVO);

    }

    @Override
    public List<PrjServiceExt> getServerList(Map<String, Object> params) {
        SysPrjservice sysPrjservice = new SysPrjservice();
        sysPrjservice.setStatus(1);
        List<PrjServiceExt> sysProjectServiceList = extSysPrjserviceMapper.getListByStatus(sysPrjservice);
        return sysProjectServiceList;
    }

    @Override
    public List<BaseQueryfield> getParamsById(Map<String, Object> params) {
        String serviceId = (String) params.get("serviceId");
        // 拿到服务信息
        SysPrjservice sysPrjservice = sysPrjserviceMapper.selectByPrimaryKey(serviceId);
        if (sysPrjservice == null) {
            return new ArrayList<>();
        }
        // 服务编号
        String servicecode = sysPrjservice.getServicecode();
        // 结果集
        List<BaseQueryfield> baseQueryfields = new ArrayList<>();
        // 根据不同的服务类型去不同的表中查询服务对应的参数      测试git 合并分支
        String servicetype = sysPrjservice.getServicetype();
        switch (servicetype) {
            case SysPrjservice.ServiceType.SINGLE_TABLE_SERVER:
                // 如果是单表服务
                baseQueryfields = extBaseQueryfieldMapper.selectAllFieldWithServiceCode(servicecode);
                break;

            case SysPrjservice.ServiceType.EXECUTE_SQL_SERVER:
                // 如果是SQL查询服务 这是创建备注  测试备注
                List<BaseSqlFieldType> list = sqlFieldTypeMapper.findByServiceId(servicecode);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                // 结果集转换
                baseQueryfields = list.stream().map(item -> {
                    BaseQueryfield baseQueryfield = new BaseQueryfield();
                    // 需要注意此处的id不是同一张表的id
                    baseQueryfield.setGuid(item.getGuid());
                    baseQueryfield.setServiceguid(serviceId);
                    baseQueryfield.setParametercode(item.getFieldName());
                    return baseQueryfield;
                }).collect(Collectors.toList());
                break;
            default:

        }


        return baseQueryfields;
    }


    @Override
    public List<BaseShowfieldExt> getResById(Map<String, Object> params) {

        String serviceId = (String) params.get("serviceId");
        SysPrjservice sysPrjservice = sysPrjserviceMapper.selectByPrimaryKey(serviceId);
        if (sysPrjservice == null) {
            return new ArrayList<>();
        }
        List<BaseShowfieldExt> baseQueryfields = extBaseShowfieldMapper.selectAllFieldWithCode(sysPrjservice.getServicecode());
        return baseQueryfields;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delByGuId(String guid) {
        sysPrjserviceMapper.deleteByPrimaryKey(guid);

        CfgMultQueryFieldExample cfgMultQueryFieldExample = new CfgMultQueryFieldExample();
        cfgMultQueryFieldExample.createCriteria().andServiceIdEqualTo(guid);
        cfgMultQueryFieldMapper.deleteByExample(cfgMultQueryFieldExample);

        CfgMultResultFieldExample resultFieldExample = new CfgMultResultFieldExample();
        resultFieldExample.createCriteria().andServiceIdEqualTo(guid);
        cfgMultResultFieldMapper.deleteByExample(resultFieldExample);


        CfgMultRelationExample relationExample = new CfgMultRelationExample();
        relationExample.createCriteria().andServiceIdEqualTo(guid);
        cfgMultRelationMapper.deleteByExample(relationExample);


        CfgMultRelationFieldExample ex = new CfgMultRelationFieldExample();
        ex.createCriteria().andServiceIdEqualTo(guid);
        cfgMultRelationFieldMapper.deleteByExample(ex);
    }

    @Override
    public String selectRelByServiceGuid(String guid) {
        CfgMultRelationExample example = new CfgMultRelationExample();
        example.createCriteria().andFirstServiceIdEqualTo(guid);
        example.or().andSecondServiceIdEqualTo(guid);
        List<CfgMultRelation> cfgMultRelations = cfgMultRelationMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(cfgMultRelations)) {
            List<String> serviceIds = cfgMultRelations.stream().map(CfgMultRelation::getServiceId).distinct().collect(Collectors.toList());
            List<SysPrjservice> sysPrjservices = extSysPrjserviceMapper.geServiceList(null, serviceIds);
            return sysPrjservices.stream().map(SysPrjservice::getServicename).distinct().collect(Collectors.joining(","));
        }
        return null;
    }

    @Override
    public Map<String, Object> getPolymInfo(Map<String, Object> map) {
        HashMap<String, Object> res = new HashMap<>();
        String servercode = (String) map.get("servercode");
        SysPrjservice projectConfigByGuid = sysPrjServiceService.getSysPrjserviceByServiceCode(servercode);
        if (projectConfigByGuid == null) {
            return res;
        }

        // 查询
        CfgMultRelationExample example = new CfgMultRelationExample();
        example.createCriteria().andServiceIdEqualTo(projectConfigByGuid.getGuid());
        List<CfgMultRelation> cfgMultRelations = cfgMultRelationMapper.selectByExample(example);

        // 查询字段配置信息
        CfgMultRelationFieldExample cfgMultRelationFieldExample = new CfgMultRelationFieldExample();
        cfgMultRelationFieldExample.createCriteria().andServiceIdEqualTo(projectConfigByGuid.getGuid());
        List<CfgMultRelationField> cfgMultRelationFields = cfgMultRelationFieldMapper.selectByExample(cfgMultRelationFieldExample);

        // 结果
        PolymRelVO relVO = new PolymRelVO();
        relVO.setCfgMultRelation(CollectionUtils.isEmpty(cfgMultRelations) ? new CfgMultRelation() : cfgMultRelations.get(0));
        relVO.setFieldList(cfgMultRelationFields);

        res.put("cfgInfo", projectConfigByGuid);
        res.put("relInfo", relVO);
        return res;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveParamsInfo(SaveParamsInfoDTO dto) {
        List<CfgMultQueryField> list = dto.getList();
        String serviceId = dto.getServiceId();
        List<CfgMultQueryField> newFiledList = dto.getNewFiledList();

        if (CollectionUtils.isEmpty(list)) {
            // 当数组为空时 考虑删除掉全部数据
            CfgMultQueryFieldExample example = new CfgMultQueryFieldExample();
            example.createCriteria().andServiceIdEqualTo(serviceId);
            List<CfgMultQueryField> cfgMultQueryFields = cfgMultQueryFieldMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(cfgMultQueryFields)) {
                return;
            }
            List<String> delIds = cfgMultQueryFields.stream().map(CfgMultQueryField::getQueryFieldId).collect(Collectors.toList());
            this.delByIds(delIds);
            return;
        }

        // 服务id
        List<String> serviceIds = list.stream().map(CfgMultQueryField::getServiceId).distinct().filter(Objects::nonNull).collect(Collectors.toList());
        List<String> ids = list.stream().map(CfgMultQueryField::getQueryFieldId).distinct().filter(Objects::nonNull).collect(Collectors.toList());

        // 根据服务id 拿到所有参数
        List<CfgMultQueryField> dbList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(serviceIds)) {
            CfgMultQueryFieldExample cfgMultQueryFieldExample = new CfgMultQueryFieldExample();
            cfgMultQueryFieldExample.createCriteria().andServiceIdIn(serviceIds);
            dbList = cfgMultQueryFieldMapper.selectByExample(cfgMultQueryFieldExample);
        }


        for (CfgMultQueryField cfgMultQueryField : list) {
            if (StringUtils.isEmpty(cfgMultQueryField.getQueryFieldId())) {
                cfgMultQueryField.setQueryFieldId(UUID.randomUUID().toString());
            }
            if (StringUtils.isEmpty(cfgMultQueryField.getNewFieldId())) {
                cfgMultQueryField.setNewFieldId(UUID.randomUUID().toString());
            }
            cfgMultQueryField.setCreatedTime(new Date());
            dbList.stream().filter(item -> item.getQueryFieldId().equals(cfgMultQueryField.getQueryFieldId())).findFirst().ifPresent(i -> {
                // 在数据库中存在
                cfgMultQueryField.setDbStatus(1);
                cfgMultQueryField.setUpdatedTime(new Date());
                cfgMultQueryField.setCreatedTime(i.getCreatedTime());
            });

        }

        // 新增
        List<CfgMultQueryField> iList = list.stream().filter(i -> i.getDbStatus() == 0).collect(Collectors.toList());
        // 更新
        List<CfgMultQueryField> uList = list.stream().filter(i -> i.getDbStatus() == 1).collect(Collectors.toList());
        // 数据库中存在但是传参不存在 就删除掉
        List<String> delIds = dbList.stream().map(CfgMultQueryField::getQueryFieldId).filter(queryFieldId -> !ids.contains(queryFieldId)).collect(Collectors.toList());
        // 新增
        if (CollectionUtils.isNotEmpty(iList)) {
            cfgMultQueryFieldMapper.insertBatch(iList);
        }
        // 更新
        if (CollectionUtils.isNotEmpty(uList)) {
            for (CfgMultQueryField cfgMultQueryField : uList) {
                cfgMultQueryFieldMapper.updateByPrimaryKey(cfgMultQueryField);
            }
        }
        // 删除
        this.delByIds(delIds);

        // 保存必填信息
        SysPrjservice sysPrjservice = this.sysPrjserviceMapper.selectByPrimaryKey(serviceId);
        String servicecode = sysPrjservice.getServicecode();
        List<BaseQueryfield> collect = newFiledList.stream().map(item -> {
            BaseQueryfield baseQueryfield = new BaseQueryfield();
            baseQueryfield.setServiceid(servicecode);
            baseQueryfield.setServicetype(10);
            baseQueryfield.setShowtype(0);
            baseQueryfield.setParametercode(item.getNewFieldCode());
            baseQueryfield.setRequiredFlag(item.getRequiredFlag());
            return baseQueryfield;

        }).collect(Collectors.toList());
         this.baseQueryfieldService.saveQueryFiled(collect);
    }


    private int delByIds(List<String> ids) {
        // 删除
        if (CollectionUtils.isNotEmpty(ids)) {
            CfgMultQueryFieldExample example = new CfgMultQueryFieldExample();
            example.createCriteria().andQueryFieldIdIn(ids);
            return cfgMultQueryFieldMapper.deleteByExample(example);
        }
        return 0;
    }

    @Override
    public List<CfgMultQueryField> getParamsInfo(Map<String, Object> params) {
        String serviceId = (String) params.get("serviceId");
        if (StringUtils.isEmpty(serviceId)) {
            return new ArrayList<>();
        }
        CfgMultQueryFieldExample e = new CfgMultQueryFieldExample();
        e.createCriteria().andServiceIdEqualTo(serviceId);
        List<CfgMultQueryField> cfgMultQueryFields = cfgMultQueryFieldMapper.selectByExample(e);
        Set<String> strings = this.baseQueryfieldService.selectRequiredFieldsByServiceGuid(serviceId);
        for (CfgMultQueryField cfgMultQueryField : cfgMultQueryFields) {
            if (strings.contains(cfgMultQueryField.getNewFieldCode())) {
                cfgMultQueryField.setRequiredFlag("1");
            } else {
                cfgMultQueryField.setRequiredFlag("0");
            }
        }
        return cfgMultQueryFields;
    }

    @Override
    public void saveResInfo(List<CfgMultResultField> list, String serviceId) {
        if (CollectionUtils.isEmpty(list)) {
            // 当数组为空时 考虑删除掉全部数据
            CfgMultResultFieldExample example = new CfgMultResultFieldExample();
            example.createCriteria().andServiceIdEqualTo(serviceId);
            List<CfgMultResultField> cfgMultQueryFields = cfgMultResultFieldMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(cfgMultQueryFields)) {
                return;
            }
            List<String> delIds = cfgMultQueryFields.stream().map(CfgMultResultField::getResultFieldId).collect(Collectors.toList());
            this.delResByIds(delIds);
            return;
        }

        // 服务id
        List<String> serviceIds = list.stream().map(CfgMultResultField::getServiceId).distinct().filter(Objects::nonNull).collect(Collectors.toList());
        List<String> ids = list.stream().map(CfgMultResultField::getResultFieldId).distinct().filter(Objects::nonNull).collect(Collectors.toList());

        // 根据服务id 拿到所有参数
        List<CfgMultResultField> dbList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(serviceIds)) {
            CfgMultResultFieldExample example = new CfgMultResultFieldExample();
            example.createCriteria().andServiceIdIn(serviceIds);
            dbList = cfgMultResultFieldMapper.selectByExample(example);
        }


        for (CfgMultResultField field : list) {
            if (StringUtils.isEmpty(field.getResultFieldId())) {
                field.setResultFieldId(UUID.randomUUID().toString());
            }
            if (StringUtils.isEmpty(field.getNewFieldId())) {
                field.setNewFieldId(UUID.randomUUID().toString());
            }
            field.setCreatedTime(new Date());
            // TODO 这里先这么存 前端需要加上一列
//            field.setNewFieldName(field.getNewFieldCode());
            dbList.stream().filter(item -> item.getResultFieldId().equals(field.getResultFieldId())).findFirst().ifPresent(i -> {
                // 在数据库中存在
                field.setDbStatus(1);
                field.setUpdatedTime(new Date());
                field.setCreatedTime(i.getCreatedTime());
            });

        }

        // 新增
        List<CfgMultResultField> iList = list.stream().filter(i -> i.getDbStatus() == 0).collect(Collectors.toList());
        // 更新
        List<CfgMultResultField> uList = list.stream().filter(i -> i.getDbStatus() == 1).collect(Collectors.toList());
        // 数据库中存在但是传参不存在 就删除掉
        List<String> delIds = dbList.stream().map(CfgMultResultField::getResultFieldId).filter(resId -> !ids.contains(resId)).collect(Collectors.toList());
        // 新增
        if (CollectionUtils.isNotEmpty(iList)) {
            cfgMultResultFieldMapper.insertBatch(iList);
        }
        // 更新
        if (CollectionUtils.isNotEmpty(uList)) {
            for (CfgMultResultField cfgMultQueryField : uList) {
                cfgMultResultFieldMapper.updateByPrimaryKey(cfgMultQueryField);
            }
        }
        // 删除
        this.delResByIds(delIds);
    }

    @Override
    public List<CfgMultResultField> getResInfo(Map<String, Object> params) {
        String serviceId = (String) params.get("serviceId");
        if (StringUtils.isEmpty(serviceId)) {
            return new ArrayList<>();
        }
        CfgMultResultFieldExample e = new CfgMultResultFieldExample();
        e.createCriteria().andServiceIdEqualTo(serviceId);
        List<CfgMultResultField> rs = cfgMultResultFieldMapper.selectByExample(e);
        return rs;
    }


    private int delResByIds(List<String> delIds) {
        // 删除
        if (CollectionUtils.isNotEmpty(delIds)) {
            CfgMultResultFieldExample example = new CfgMultResultFieldExample();
            example.createCriteria().andResultFieldIdIn(delIds);
            return cfgMultResultFieldMapper.deleteByExample(example);
        }
        return 0;
    }

    private void saveFieldRel(PolymRelVO re) {
        List<CfgMultRelationField> fieldList = re.getFieldList();
        CfgMultRelation cfgMultRelation = re.getCfgMultRelation();
        List<String> delRelFields = re.getDelRelFieldList();
        if (CollectionUtils.isEmpty(fieldList)) {
            return;
        }

        List<String> collect = fieldList.stream().map(CfgMultRelationField::getRelationFieldId).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        List<CfgMultRelationField> cfgMultRelationFields = new ArrayList<>();
        if (!CollectionUtils.isEmpty(collect)) {
            CfgMultRelationFieldExample cfgMultRelationFieldExample = new CfgMultRelationFieldExample();
            cfgMultRelationFieldExample.createCriteria().andRelationFieldIdIn(collect);
            cfgMultRelationFields = cfgMultRelationFieldMapper.selectByExample(cfgMultRelationFieldExample);
        }


        // 设置配置信息
        for (CfgMultRelationField cfgMultRelationField : fieldList) {
            if (StringUtils.isEmpty(cfgMultRelationField.getRelationFieldId())) {
                cfgMultRelationField.setRelationFieldId(UUID.randomUUID().toString());
            }
            cfgMultRelationField.setServiceId(cfgMultRelation.getServiceId());
            cfgMultRelationField.setFirstServiceId(cfgMultRelation.getFirstServiceId());
            cfgMultRelationField.setSecondServiceId(cfgMultRelation.getSecondServiceId());
            cfgMultRelationField.setCondition(cfgMultRelation.getCondition());
            cfgMultRelationField.setCreatedTime(new Date());
            cfgMultRelationFields.stream().filter(item -> item.getRelationFieldId().equals(cfgMultRelationField.getRelationFieldId())).findFirst().ifPresent(res -> {
                // 在数据库中存在
                cfgMultRelationField.setDbStatus(1);
                cfgMultRelationField.setUpdatedTime(new Date());
                cfgMultRelationField.setCreatedTime(res.getCreatedTime());
            });
        }

        // 新增
        List<CfgMultRelationField> iList = fieldList.stream().filter(i -> i.getDbStatus() == 0).collect(Collectors.toList());
        // 更新
        List<CfgMultRelationField> uList = fieldList.stream().filter(i -> i.getDbStatus() == 1).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(iList)) {
            cfgMultRelationFieldMapper.insertBatch(iList);
        }
        // 删除
        if (!CollectionUtils.isEmpty(delRelFields)) {
            CfgMultRelationFieldExample cfgMultRelationFieldExample = new CfgMultRelationFieldExample();
            cfgMultRelationFieldExample.createCriteria().andRelationFieldIdIn(delRelFields);
            cfgMultRelationFieldMapper.deleteByExample(cfgMultRelationFieldExample);
        }

        if (!CollectionUtils.isEmpty(uList)) {
            // TODO 先循环更新
            for (CfgMultRelationField cfgMultRelationField : uList) {
                cfgMultRelationFieldMapper.updateByPrimaryKey(cfgMultRelationField);
            }
        }

    }


    /**
     * 保存 表和表之间的关联关系
     *
     * @param relVO
     */
    private void saveRel(CfgMultRelation relVO) {
        String relationId = relVO.getRelationId();
        CfgMultRelation cfgMultRelation = cfgMultRelationMapper.selectByPrimaryKey(relationId);
        String sercode = relVO.getServiceCode();
        if (StringUtils.isEmpty(sercode)) {
            return;
        }
        SysPrjservice sysPrjserviceByServiceCode = sysPrjServiceService.getSysPrjserviceByServiceCode(sercode);
        if (sysPrjserviceByServiceCode == null) {
            return;
        }
        relVO.setServiceId(sysPrjserviceByServiceCode.getGuid());
        if (cfgMultRelation == null) {
            relVO.setRelationId(UUID.randomUUID().toString());
            relVO.setCreatedTime(new Date());
            cfgMultRelationMapper.insertSelective(relVO);
        } else {
            relVO.setUpdatedTime(new Date());
            cfgMultRelationMapper.updateByPrimaryKeySelective(relVO);
        }

    }


}
